home *** CD-ROM | disk | FTP | other *** search
- ******************************************************************************
- Wilfried Cordes, Kennedystraße 20, 2900 Oldenburg
- ******************************************************************************
- Beschreibung zu PFFR.PRG
- ******************************************************************************
- Oldenburg, 14.9.'90
-
- PFFR ist frei kopierbar. Es ist allerdings nicht erwünscht, daß das Programm
- verkauft oder mit kommerziellen Programmen zusammen vertrieben wird.
-
- Wer das Programm häufiger benutzt, sollte dem Autor DM 20,-- zukommen lassen.
- Dafür gibt es dann noch die aktuellste Version zurück.
-
- PFFR ist ein kleiner Druckerspooler, der hauptsächlich dazu dient, die
- Druckausgabe zu beschleunigen, weniger den Rechner frühzeitig freizugeben.
- Die Beschleunigung des Druckens resultiert daraus, daß an Stelle der
- BIOS-Druckausgabe nach dem Pollingprinzip eine interruptgesteuerte
- Druckausgabe erfolgt.
-
- Polling bedeutet, daß vor jeder Ausgabe auf den Druckerausgang nachgeschaut
- wird, ob die 'BUSY'-Leitung am Druckerausgang auf logisch 'HIGH' liegt. Wenn
- dies der Fall ist, ist entweder der Puffer des Druckers voll oder es ist gar
- keiner angeschlossen. TOS wartet nun maximal dreißig Sekunden und kehrt dann
- mit Fehlermeldung zurück.
-
- Eine interruptgesteuerte Ausgabe hat nun den großen Vorteil, daß sie nicht
- nachschauen muß, ob der Drucker 'BUSY' ist. Die Interruptroutine kommt immer
- dann ans Ruder, wenn der Zustand der 'BUSY'-Leitung von logisch 'HIGH' auf
- logisch 'LOW' wechselt, der Drucker also seine Bereitschaft zu erkennen gibt,
- weitere Zeichen anzunehmen.
- Dieser Interrupt ist normalerweise gesperrt, da er vom Betriebssystem nicht
- benutzt wird. Er läßt sich jedoch recht leicht aktivieren.
-
- Zu diesem Zweck wird wie folgt vorgegangen:
-
- 1) In den BUSYInterruptvektor hex. $100, dez. 256, wird die Adresse der
- Routine eingetragen, die die Druckausgabe erledigen soll.
-
- 2) Die Leitung 0 (von acht) des E/A-Ports des MFP (Multi Function Peripheral)
- wird als Eingang geschaltet. Hier liegt die BUSYleitung des Druckerports
- an. Das Schalten auf Eingang geschieht durch das Löschen des Bits 0 im
- MFP-'Data Direction Register' (DDR). Dies ist zwar schon der normale
- Zustand, aber sicher ist sicher....
-
- 3) Im MFP-'Active Edge Register' (AER) wird Bit 0 gelöscht. Dies stellt
- sicher, daß der BUSYInterrupt beim Übergang von 'HIGH' auf 'LOW' ausgelöst
- wird.
-
- 4) Als vorletzte Aktion wird die Ausmaskierung des BUSYInterrupt aufgehoben,
- indem Bit 0 des MFP-'Interrupt Mask Registers B' (IMRB) gesetzt wird.
- Bit 0 des MFP-Registers B steuert die Interrupts an Leitung 0 des MFP, was
- ja die BUSYleitung ist ....
-
- 5) Zu guter Letzt (fast) wird Bit 0 im MFP-'Interrupt Enable Register B'
- gesetzt und damit der Interrupt endlich eingeschaltet.
-
- Soweit, so schön. Aber:
- Warum sollte die BUSYleitung jemals von 'besetzt' auf 'frei' umschalten, wenn
- sie niemals auf 'besetzt' war?
- Wo kriegen wir die Zeichen her, die auf's Papier sollen?
- Wie kriegen wir die Routinen dauerhaft im Speicher installiert?
-
- Für die letzte Frage gibt es zwei mögliche Antworten:
-
- 1) Eine Installation als Accessory.
-
- 2) Eine Installation als speicherresidentes Programm zum Beispiel für den
- AUTOordner.
-
- Diese zweite Möglichkeit wurde für PFFR gewählt. Der Vorteil sind
- hauptsächlich eine geringere Programmgröße und ein geringerer
- Programmieraufwand. Außerdem blockiert PFFR keinen Eintrag im Deskmenü, an
- denen ja sowieso stets Mangel herrscht.
-
- Der Speicher für den Puffer wird aber nicht zur Laufzeit angefordert, sondern
- beim Start reserviert.
- Dies hat leider zur Folge, daß der Puffer immer im Speicher ist, auch wenn
- er inaktiv ist.
-
- --------------------------------------------------------------------------
- Die Größe des Puffers wird in Namen eincodiert. Die 5. bis 8. Position des
- Namens geben die Puffergröße an:
- PFFR0110 -> 110 KBytes, PFFR0005 -> 5 Kbytes.
- Alle vier Buchstaben müssen besetzt sein!
- --------------------------------------------------------------------------
-
- Schon fünf Kbytes bringen eine deutliche Beschleunigung der Druckausgabe.
-
- Wo kommen nun die Zeichen her, die vom BUSYInterrupt an den Drucker gegeben
- werden können?
-
- Eine halbe Antwort gab's bereits im vorigen Absatz: Aus einem Puffer, der beim
- Programmstart im RAM des Rechners angelegt wird.
-
- Die Druckausgabe des ATARI erfolgt über die BIOSfunktion Nr. 3 'BCONOUT'.
- Alle Zeichen, die zum Drucker sollen, müssen hier vorbei. Was liegt also
- näher, als diesen Ausgang umzubiegen auf eine Routine, die die betreffenden
- Zeichen in den Druckerpuffer schreibt. Das wird nun auch getan, wobei aber
- zwei Dinge zu beachten sind:
-
- Erstens ist 'BCONOUT' die Standardausgabefunktion für alle Geräte, als da
- wären Bildschirm, Tastatur, MIDI- und V.24-Schnittstelle sowie der Drucker-
- ausgang. Die neue Routine muß also noch die Gerätenummer prüfen, bevor das
- Zeichen in den Puffer geschrieben wird. Falls ein anderes Gerät angesprochen
- wird, muß die Originalroutine angesprungen werden.
-
- Zweitens kann diese Funktion im USER- oder im SUPERVISORmodus aufgerufen wer-
- den. Im ersten Fall liegen die Daten auf dem USERStapel, ansonsten auf den
- SUPERVISORStapel. Beim Aufruf im SUPERVISORmodus liegen noch das
- Statusregister (SR, Wort) und der Programmzähler (PC, Langwort) mit auf dem
- Stapel, so daß die benötigten Daten alle um sechs Bytes höher auf dem Stapel
- liegen.
-
- Außerdem bedient PFFR noch die BIOSfunktion BCOSTAT (Nr. 8), die den
- Ausgabestatus der parallelen Schnittstelle liefert. Hier wird stattdessen
- zurückgegeben, ob der Puffer voll ist oder nicht.
-
- Die letzte offene Frage nach dem Anstoßen des BUSYInterrupts kann wie folgt
- beantwortet werden:
-
- Es wird ein weiterer Interrupt angezapft und zwar der 'etv_timer'-Interrupt,
- der 50 mal pro Sekunde auftritt und vom Systemtimer ausgelöst wird. Die
- Adresse der Interruptroutine steht in der Systemvariable 'etv_timer' auf
- Adresse hex. $400, dez. 1024. Hier wird die Adresse einer eigenen Routine
- eingetragen, die die erste Druckausgabe erledigt, bis der BUSYInterrupt
- ihm die Arbeit abnimmt. Das eigene Programm muß nach erledigter Arbeit
- noch dafür sorgen, daß die Systemroutinen wieder angesprungen werden.
-
- PFFR rettet die Adressen der Betriebssystemroutinen in sogenannten 'XBRA'-
- Strukturen:
-
- typedef struct
- {
- char xb_magic[4]; /* "XBRA" -> Strukturkennung */
- char xb_id[4]; /* "DPVA" -> Programmkennung */
- long xb_oldvec; /* vorherige Adresse des Vektors */
- } XBRA;
-
- Damit ist es dem Programm möglich, zu erkennen, ob es schon installiert
- worden ist und zweitens kann es sich auch wieder ausklinken. Schließlich ist
- es auch anderen Programmen möglich, den Druckerpuffer zu identifizieren.
-
- In PUFFER gibt es somit drei XBRAStrukturen. eine vor der neuen BIOSroutine,
- eine vor der BUSYinterrupt- und eine vor der etv_timer-Routine.
-
- Beim Programmstart prüft das Programm aber nur die Busystruktur!
- Dies kann in unglücklichen Fällen zu einiger Wirrnis führen, wenn nämlich ein
- anderes Programm den BIOS- oder den etv_timer-Interrupt testen, aber nicht
- den BIOSvektor. Da aber nur der Busyinterrupt von maximal einer Routine
- genutzt werden kann, der etv_timer und das BIOS aber mehrere Treiber
- vertragen, ist das nicht so problematisch.
-
- Zum Schluß noch eine Erklärung zur eigentlichen Druckausgabe. Die
- Vorgehensweise ist wie folgt:
-
- - Interrupts sperren.
-
- - Nachschauen, ob der Drucker BUSY ist, was er eigentlich nicht sein kann, da
- die Routine ja gerade dann angesprungen wird, wenn der Drucker die
- BUSYleitung freigibt, aber der etv_timer liefert ja auch Daten.
-
- - Nachschauen, ob überhaupt ein Zeichen im Puffer zur Ausgabe ansteht.
-
- - Nun wird ein Zeichen auf die acht Datenleitungen der
- Centronics-Schnittstelle gelegt, indem es in den Port B des 'Programmable
- Sound Generators' (PSG) geschrieben wird.
-
- - Nun muß noch die 'STROBE'-Leitung, auf der dem Drucker mitgeteilt wird, daß
- das Byte auf der Leitung gedruckt werden soll, kurzzeitig auf logisch 'LOW'
- gehen. Die STROBEleitung liegt an Bit 5 des Port A des PSG's.
-
- - Abschließend wird Bit 0 'Interrupt in Service Register B' gelöscht, womit
- angezeigt ist, daß der BUSYInterrupt bedient worden ist. (Dies natürlich
- nur, falls die Schreibroutine vom BUSYinterrupt aufgerufen worden ist,
- falls der etv_timer-Interrupt die Routine aufgerufen hat, werden nur die
- Interrupts wieder freigegeben.)
-
- Kein Gewähr für Fehlerfreiheit, keine Haftung für Schäden, die evtl. durch
- Fehler in PFFR verursacht werden.
-
- *E*N*D*E* *E*N*D*E* *E*N*D*E* *E*N*D*E* *E*N*D*E* *E*N*D*E* *E*N*D*E*
-